/*
 * This is the command line parsing functions
 * Where command function will be requested to add from code generator GUI.
 * Command function will be refreshed in cmd_list[], command.h, and it's
 * definition in this file automatically.
 */
#include <string.h>
#include <stdlib.h>

#include "global.h"
#include "serial.h"
#include "command.h"
#include "spi.h"


cmd_type cmd_list[] = {
    {"list",             "show the list of these commands",              List},
    {"setReg",           "set 2829's register",                          SetReg},
    {"testReceive",      "test receive,BOARD_A receive, BOARD_B transmit",TestReceive},
    {0}
};

/*
 *atoi was rewritten as _atoi because it defaults not supported hex,
 *now hex and dec was supported
 */
uint16 _atoi(char *buf)
{
    char c;
    uint16 ret = 0;
    uint16 len = strlen(buf), i;
    if(strlen(buf) >= 2 && buf[0] == '0'&& buf[1] == 'x'){
        for(i = 2; i < len; i++){
            if(buf[i] >= 'a' && buf[i] <='f') c = buf[i]-'a'+10;
            else if(buf[i] >= 'A' && buf[i] <='F') c = buf[i]-'A'+10;
            else c = buf[i] - '0';
            ret = c + 16*ret;
        }
    }
    else sscanf(buf, "%d", &ret);
    return ret;	
}


void List(uint8 argc, uint8 *argv[])
{
    uint8 i;
    print("-----------------------------------------\r\n");
    for(i = 0; cmd_list[i].cmd[0] != 0; i++){
        print(cmd_list[i].cmd);
        print("\t\t");
        print(cmd_list[i].longcmd);
        print("\r\n");
    }
    print("-----------------------------------------\r\n");
}

void SetReg(uint8 argc, uint8 *argv[])
{
    uint8 reg;
    uint16 value;
    char buf[10];
    if(argc != 3 && argc != 4) return;
    reg = _atoi(argv[1]);
    value = _atoi(argv[2]);
    if(argc == 3){
        set_register(reg, value, BOARD_A);
        set_register(reg, value, BOARD_B);
    }else
        set_register(reg, value, _atoi(argv[3]));
    print("set register.\t\t[done]");
}

void TestReceive(uint8 argc, uint8 *argv[])
{
    if(argc != 1) return;
    parse_and_run("setReg 5 0x1822");
    parse_and_run("enableSW2 0");
    parse_and_run("disableSW1 0");
    parse_and_run("enableSW1 1");
    parse_and_run("disableSW2 1");
    parse_and_run("receive 0"); //BOARD_A receive mode.
    parse_and_run("transmit 1"); //BOARD_B transmit mode.
    print("set BORAD_A receive and BORAD-B transmit\t\t[done]\r\n");
}


static uint8 argc;
static uint8 *argv[MAX_ARGS];
/* parse args, which will be delim by whitespace and tab*/
static void parse_args(char *s)
{
    char *p = s;
    argc = 0;
    for(;;){
        while(*p==' ' || *p=='\t') {*p = '\0'; p++;}
        if(*p == '\0') return;
        argv[argc] = p;
        argc++;
        while(*p != ' ' && *p != '\t' && *p != '\0') p++;
    }
}

/* run the command */
static bool run_cmd()
{
    int i;
    if(argc == 0) return False;
    for(i = 0; cmd_list[i].cmd[0] != 0; i++){
        if(strcmp(cmd_list[i].cmd, argv[0]) == 0){
            cmd_list[i].proc(argc, argv);
            return True;
        }
    }
    return False;
}

/* api to other files, for parsing and run the command */
bool parse_and_run(char *line)
{
    parse_args(line);
    return run_cmd();
}
